package com.lujieni.springbootmybatis.interceptor;

import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.lujieni.springbootmybatis.aop.TenantIgnore;
import com.lujieni.springbootmybatis.context.TenantContextHolder;
import com.lujieni.springbootmybatis.po.TenantDO;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.schema.Column;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class TenantDatabaseInterceptor implements TenantLineHandler {

    private final Map<String, Boolean> TENANT_FIELD_EXISTS_CACHE = new ConcurrentHashMap<>();

    @Override
    public Expression getTenantId() {
        // 返回当前租户ID的实际值，通常从ThreadLocal或SecurityContext获取
        Long tenantId = TenantContextHolder.getRequiredTenantId();
        return new LongValue(tenantId);
    }

    @Override
    public boolean ignoreTable(String tableName) {
        // 情况一，全局忽略多租户
        return TenantContextHolder.isIgnore() || !isTenantFiledExists(tableName);
    }

    @Override
    public boolean ignoreInsert(List<Column> columns, String tenantIdColumn) {
        return TenantLineHandler.super.ignoreInsert(columns, tenantIdColumn);
    }

    private boolean isTenantFiledExists(String tableName) {
        Boolean flag = this.TENANT_FIELD_EXISTS_CACHE.get(tableName);
        if (flag != null) {
            return flag;
        } else {
            boolean result = TableInfoHelper.getTableInfo(tableName).getFieldList().stream().anyMatch(f -> "tenant_id".equals(f.getColumn()));
            this.TENANT_FIELD_EXISTS_CACHE.put(tableName, result);
            return result;
        }
    }

    private boolean computeIgnoreTable(String tableName) {
        // 找不到的表，说明不是 yudao 项目里的，不进行拦截（忽略租户）
        TableInfo tableInfo = TableInfoHelper.getTableInfo(tableName);
        if (tableInfo == null) {
            return true;
        }
        // 如果继承了 TenantBaseDO 基类，显然不忽略租户
        if (TenantDO.class.isAssignableFrom(tableInfo.getEntityType())) {
            return false;
        }
        // 如果添加了 @TenantIgnore 注解，显然也不忽略租户
        TenantIgnore tenantIgnore = tableInfo.getEntityType().getAnnotation(TenantIgnore.class);
        return tenantIgnore != null;
    }
}
